package cn.dm.service;

import cn.dm.client.RestDmUserClient;
import cn.dm.common.*;
import cn.dm.pojo.DmUser;
import cn.dm.vo.DmUserRegisterVO;
import cn.dm.vo.DmUserVO;
import cn.dm.vo.QueryUserVo;
import cn.dm.vo.TokenVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Pattern;

@Service
public class LocalUserServiceImpl implements LocalUserService {
    @Resource
    private SmsService smsService;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private RestDmUserClient restDmUserClient;
    @Resource
    private ObjectMapper objectMapper;

    private boolean validPhone(String phone) {
        String regex = "^1[35789]{1}\\d{9}$";
        return Pattern.compile(regex).matcher(phone).find();
    }

    @Override
    public Dto code(String phone) throws Exception {
        Dto dto = null;
        try {
            String key = "phone:" + phone;
            Dto checkEmailDto = this.checkEmail(phone);
            System.out.println(checkEmailDto.getSuccess());
            if ("true".equals(checkEmailDto.getSuccess())) {
                if (!redisUtils.exist(key)) {
                    //1.生成短信验证码
                    String code = String.valueOf(MD5.getRandomCode());
                    //2.发送短信验证码
                    String[] datas = {code, "5"};
                    smsService.sendSmsMessage(phone, "1", datas);
                    //3.将短信验证码存储到Redis中
                    redisUtils.set(key, 60 * 5, code);
                    dto = DtoUtil.returnSuccess("验证码已发送");
                } else {
                    dto = DtoUtil.returnFail("冻结时间未到", "1002");
                }
            } else {
                dto = checkEmailDto;
            }
        } catch (Exception e) {
            dto = DtoUtil.returnFail("验证码发送失败", "1007");
            e.printStackTrace();
        } finally {
            return dto;
        }
    }

    @Override
    public Dto checkEmail(String phone) throws Exception {
        if (validPhone(phone)) {
            Map<String, Object> param = new HashMap<>();
            param.put("phone", phone);

            if (restDmUserClient.getDmUserCountByMap(param) == 0) {
                return DtoUtil.returnSuccess();
            } else {
                return DtoUtil.returnFail("手机号已注册", "1003");
            }
        } else {
            return DtoUtil.returnFail("手机号格式错误", "1001");
        }
    }

    @Override
    public Dto register(DmUserRegisterVO dmUserRegisterVO) throws Exception {
        Dto dto = null;
        Dto checkEmailDto = this.checkEmail(dmUserRegisterVO.getPhone());
        if ("true".equals(checkEmailDto.getSuccess())) {
            String code = (String) redisUtils.get("phone:" + dmUserRegisterVO.getPhone());
            if (EmptyUtils.isNotEmpty(code) || code.equals(dmUserRegisterVO.getVcode())) {
                DmUser user = new DmUser();
                user.setPhone(dmUserRegisterVO.getPhone());
                String password = MD5.getMd5(dmUserRegisterVO.getPassword(), 32);
                user.setPassword(password);
                user.setCreatedTime(new Date());
                if (restDmUserClient.qdtxAddDmUser(user) > 0) {
                    dto = DtoUtil.returnSuccess("注册成功");
                }
            } else {
                dto = DtoUtil.returnFail("验证码错误", "1004");
            }
        } else {
            dto = checkEmailDto;
        }
        return dto;
    }

    @Override
    public Dto login(String phone, String password) throws Exception {
        Dto dto = null;
        DmUser loginUser = new DmUser();
        loginUser.setPhone(phone);
        loginUser.setPassword(MD5.getMd5(password, 32));
        DmUser user = restDmUserClient.checkLoginByPassword(loginUser);
        if (EmptyUtils.isNotEmpty(user)) {
            String token = restDmUserClient.generateToken(user);
            TokenVO tokenVO = new TokenVO();
            tokenVO.setToken(token);
            tokenVO.setExpTime(Constants.Redis_Expire.SESSION_TIMEOUT);
            tokenVO.setGenTime(new Date().getTime());
            DmUserVO dmUserVO = new DmUserVO();
            BeanUtils.copyProperties(user, dmUserVO);
            dmUserVO.setUserId(user.getId());
            String userVOJSON = objectMapper.writeValueAsString(dmUserVO);
            redisUtils.set(Constants.USER_TOKEN_PREFIX, Constants.Redis_Expire.SESSION_TIMEOUT, userVOJSON);
            List list = new ArrayList();
            list.add(dmUserVO);
            list.add(tokenVO);
            dto = DtoUtil.returnSuccess("登陆成功", list);
        } else {
            dto = DtoUtil.returnFail("账号或密码错误", "1006");
        }
        return dto;
    }

    @Override
    public Dto queryUserInfoByToken() throws Exception {
        String token = (String) redisUtils.get(Constants.USER_TOKEN_PREFIX);
        DmUserVO userVO = objectMapper.readValue(token, DmUserVO.class);
        QueryUserVo queryUserVo = new QueryUserVo();
        BeanUtils.copyProperties(userVO, queryUserVo);
        queryUserVo.setId(userVO.getUserId());
        return DtoUtil.returnDataSuccess(queryUserVo);
    }

    @Override
    public Dto modifyUserInfo(QueryUserVo queryUserVo) throws Exception {
        String token = (String) redisUtils.get(Constants.USER_TOKEN_PREFIX);
        DmUserVO userVO = objectMapper.readValue(token, DmUserVO.class);
        DmUser user = new DmUser();
        BeanUtils.copyProperties(queryUserVo, user);
        user.setId(userVO.getUserId());
        user.setUpdatedTime(new Date());
        if (restDmUserClient.qdtxModifyDmUser(user) > 0) {
            return DtoUtil.returnDataSuccess("修改成功");
        } else {
            return DtoUtil.returnFail("修改失败", "");
        }
    }

    @Override
    public DmUser findUserByWxId(String openId) throws Exception {
        return restDmUserClient.findByWxUserId(openId);
    }

    @Override
    public Long createUser(DmUser dmUser) throws Exception {
        return restDmUserClient.createDmUser(dmUser);
    }

    @Override
    public String genToken(DmUser dmUser) throws Exception {
        return restDmUserClient.generateToken(dmUser);
    }
}
